home *** CD-ROM | disk | FTP | other *** search
/ A.C.E. 2 / ACE CD 2.iso / FILES / UTILS / GAMESDS3.DMS / GAMESDS3.adf / GDS_Examples.lha / Examples / aqua / aqua.c < prev    next >
C/C++ Source or Header  |  1994-11-14  |  24KB  |  715 lines

  1. /* Aqua demo by John Enright.  Graphics (c) Mike Alkan */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <exec/memory.h>
  7. #include <exec/types.h>
  8. #include <graphics/gfx.h>
  9. #include <graphics/gfxbase.h>
  10.  
  11. #include <proto/exec.h>
  12. #include <proto/graphics.h>
  13. #include <proto/intuition.h>
  14.  
  15. #include "GameSmith:GameSmith.h"
  16. #include "GameSmith:include/proto/all_regargs.h"
  17. #include "GameSmith:include/libraries/libptrs.h"
  18.  
  19. #define DISPLAY_SIZE   320            /* lores display resolution horizontal */
  20.  
  21. #define PAGE_SIZE   (DISPLAY_SIZE*4)   /* actual scrollable bitmap size */
  22.  
  23. #define BMDEPTH   4                  /* depth of bitmap (16 color) */
  24. #define BMOFFSET   48         /* buffer amount (in pixels) for anims & display offset */
  25. #define BMWIDTH   (PAGE_SIZE+(BMOFFSET*2))   /* actual width of bitmap */
  26. #define BMHEIGHT   192               /* height of bitmap.  All of this is visible */
  27.  
  28. #define VS_X         (PAGE_SIZE*10)   /* width of virtual space for object traversal */
  29. #define LEFT_BOUNDS   BMOFFSET         /* left boundary for anim objects */
  30. #define RIGHT_BOUNDS   (VS_X+BMOFFSET)   /* right boundary for anim objects */
  31. #define TOP_BOUNDS   16               /* top boundary for anim objects */
  32. #define BOTTOM_BOUNDS 184            /* bottom boundary for anim objects */
  33. #define BOTTOM_SPACE   16         /* vertical rows on sea bottom for obj placement */
  34.  
  35. #define ANIM_SPEED   4         /* pixel speed for object movement */
  36.  
  37. #define ANIM_COUNT   18         /* number of objects in each array */
  38.  
  39. #define VB_DELAY      5         /* the fastest objects are allowed to animate */
  40.  
  41. #define FRAME_RATE   1         /* scroll rate in vertical blank intervals */
  42.  
  43. /*-------------------------------------------------------------------------*/
  44. /* Function Prototypes                                                      */
  45.  
  46. void scroll(void);
  47. int setup(void);
  48. int place_anim_bottom(struct anim_struct *);
  49. int place_cplx_bottom(struct anim_cplx *);
  50. int place_cplx(struct anim_cplx *);
  51. void move_creatures(void);
  52. void move_anim(struct anim_struct *);
  53. void move_cplx(struct anim_cplx *);
  54. void check_bounds(void);
  55. void check_anim_bounds(struct anim_struct *);
  56. void check_cplx_bounds(struct anim_cplx *);
  57. int check_close(void);
  58. void cleanup(void);
  59.  
  60. /*-------------------------------------------------------------------------*/
  61. /* some global variables                                                   */
  62.  
  63. struct Interrupt *scroller=NULL;
  64. unsigned long color[1<<BMDEPTH];   /* color table with 2 to the power of BMDEPTH entries */
  65. int dlist=-1;                     /* display list handle for anims */
  66.  
  67. int rs_offset=0,window,reset=0;
  68.  
  69. /* ---- the anim object array pointers ---- */
  70.  
  71. struct anim_struct *rollcrab=NULL,*coral1=NULL,*coral2=NULL,*coral3=NULL;
  72. struct anim_cplx *fish1=NULL,*fish2=NULL,*fish3=NULL;
  73. struct anim_cplx *aquadino=NULL;
  74.  
  75. /*-------------------------------------------------------------------------*/
  76.  
  77. BitMapHeader bmh;
  78.  
  79. struct loadILBM_struct loadpic =
  80.    {
  81.    "gfx/aqua.pic",   /* ptr to picture name string */
  82.    NULL,               /* ptr to 1st bitmap */
  83.    NULL,               /* ptr to 2nd bitmap (if any) */
  84.    color,            /* ptr to color table array */
  85.    (1<<BMDEPTH),      /* # colors in color table */
  86.    NULL,               /* height of image in pixels (filled by load call) */
  87.    NULL,               /* width of image in pixels (filled) */
  88.    NULL,               /* x display offset (filled) */
  89.    NULL,               /* y display offset (filled) */
  90.    NULL,               /* pic mode (filled) */
  91.    BMOFFSET/8,         /* x load offset (from left) in bytes */
  92.    0,                  /* y load offset (from top) in rows */
  93.    ILBM_COLOR,         /* flags (fill color table) */
  94.    0xff,               /* bitplane fill mask */
  95.    0xff,               /* bitplane load mask */
  96.    &bmh               /* address of BitMapHeader to fill */
  97.    };
  98.  
  99. struct gs_viewport vp =
  100.    {
  101.    NULL,                           /* ptr to next viewport */
  102.    color,                        /* ptr to color table */
  103.    (1<<BMDEPTH),                  /* number of colors in table */
  104.    NULL,                           /* ptr to user copper list */
  105.    BMHEIGHT,DISPLAY_SIZE,BMDEPTH,BMHEIGHT,BMWIDTH, /* height, width, depth, bmheight, bmwidth */
  106.    0,0,                           /* top & left viewport offsets */
  107.    BMOFFSET,0,                     /* X & Y bitmap offsets */
  108.    GSVP_ALLOCBM,                  /* flags (allocate bitmaps) */
  109.    NULL,NULL,                     /* 2.xx & above compatibility stuff */
  110.    NULL,NULL,                     /* bitmap pointers */
  111.    NULL,                           /* future expansion */
  112.    0,0,0,0                        /* display clip (MinX,MinY,MaxX,MaxY) */
  113.    };
  114.  
  115. struct display_struct display =
  116.    {
  117.    NULL,                           /* ptr to previous display view */
  118.    NULL,NULL,                     /* 2.xx & above compatibility stuff */
  119.    0,0,                           /* X and Y display offsets (1.3 style) */
  120.    0,                              /* display mode ID */
  121.    4,4,                           /* sprite priorities */
  122.    GSV_DOUBLE|GSV_SCROLLABLE|
  123.    GSV_HARDX,                     /* flags (scrollable double buffered) */
  124.    &vp,                           /* ptr to 1st viewport */
  125.    NULL                           /* future expansion */
  126.    };
  127.  
  128. /***************************************************************************/
  129.  
  130. main(argc,argv)
  131. int argc;
  132. char *argv[];
  133.  
  134. {
  135.    int err,end=0;
  136.  
  137.    if (gs_open_libs(DOS|GRAPHICS,0))   /* open AmigaDOS libs, latest versions */
  138.       exit(01);               /* if can't open libs, abort */
  139.    if (err=setup())            /* if couldn't get set up... abort program */
  140.       {
  141.       printf("\nSetup error: %d\n",err);
  142.       gs_close_libs();         /* close all libraries */
  143.       exit(02);
  144.       }
  145.    Forbid();                  /* take over the entire machine */
  146.    while (!end)               /* this shows off speed */
  147.       {
  148.       move_creatures();         /* animate everything */
  149.       end=check_close();      /* end when user hits left mouse button */
  150.       }
  151.    Permit();                  /* OK, let other things run while we clean up */
  152.    cleanup();                  /* close & deallocate everything */
  153.    gs_close_libs();            /* close all libraries */
  154. }
  155.  
  156. /***************************************************************************/
  157. /*
  158.    This is the scroll handler which runs as a vertical blank server routine
  159.    and handles scrolling of the bitmap.  This is the reason for its ultra-
  160.    smooth performance, regardless of what the animation system is doing.
  161.  
  162.    The "__interrupt" is a SAS convention used to make sure that the function
  163.    does NOT do stack checking.  The "__saveds" is also a SAS convention, and
  164.    loads the near data pointer at the beginning of the function.
  165.  
  166. */
  167.  
  168. void __interrupt __saveds scroll()
  169.  
  170. {
  171.    int stick,x=0,diff,velocity=1,shift=0;
  172.    static int x_offset=0,dir_right=1,flop=0,page=0;
  173.  
  174.    flop++;
  175.    if (flop < FRAME_RATE)         /* check against frame rate */
  176.       return;                     /* if not time to scroll, abort */
  177.    flop=0;
  178.    stick = _gs_joystick(1);      /* poll joystick */
  179.    if (stick & (JOY_LEFT|JOY_RIGHT|JOY_BUTTON1))
  180.       {                           /* if joystick value we're concerned with */
  181.       velocity*=3;               /* increase velocity */
  182.       if (stick & JOY_BUTTON1)   /* button holds display */
  183.          velocity=0;
  184.       if (stick & JOY_LEFT)
  185.          x=-velocity;
  186.       else if (stick & JOY_RIGHT)
  187.          x=velocity;
  188.       }
  189.    else
  190.       {
  191.       if (dir_right)      /* if scrolling right */
  192.          {
  193.          x=velocity;
  194.          }
  195.       else               /* else scrolll left */
  196.          {
  197.          x=-velocity;
  198.          }
  199.       }
  200.    x_offset+=x;
  201.    if ((x_offset + DISPLAY_SIZE) >= VS_X)      /* check against scroll boundaries */
  202.       {                                       /* don't go past virtual space used by anims */
  203.       dir_right=0;
  204.       x_offset=VS_X-DISPLAY_SIZE;;
  205.       x=0;
  206.       }
  207.    else if (x_offset < 0)
  208.       {
  209.       dir_right=1;
  210.       x_offset=0;
  211.       x=0;
  212.       }
  213.    if (x)
  214.       {
  215.       diff=vp.xoff+x-BMOFFSET;
  216.       if (diff < 0)                           /* if past beginning of actual bitmap */
  217.          {
  218.          x=(PAGE_SIZE-DISPLAY_SIZE)+x;         /* shift to end of bitmap & keep scrolling */
  219.          shift=1;                              /* this provides a seemless transition, and */
  220.          if (!page)
  221.             {
  222.             reset=1;
  223.             rs_offset-=PAGE_SIZE-DISPLAY_SIZE;
  224.             window=PAGE_SIZE-DISPLAY_SIZE;   /* adjust real space window */
  225.             }
  226.          page=0;
  227.          }                                    /* gives the illusion of an infinite horizon */
  228.       else if (((diff-velocity) < 0))         /* early warning system. :) */
  229.          {                                    /* notify main program of upcoming bitmap shift */
  230.          if ((x_offset-velocity) > 0)
  231.             {
  232.             rs_offset-=PAGE_SIZE-DISPLAY_SIZE;
  233.             window=PAGE_SIZE-DISPLAY_SIZE;   /* adjust real space window */
  234.             reset=1;                           /* flag to reset bitmap pointers */
  235.             page=1;
  236.             }
  237.          }
  238.       else if (diff >= (PAGE_SIZE-DISPLAY_SIZE))
  239.          {
  240.          x=-((PAGE_SIZE-DISPLAY_SIZE)-x);
  241.          shift=1;
  242.          if (!page)
  243.             {
  244.             reset=1;
  245.             rs_offset+=PAGE_SIZE-DISPLAY_SIZE;
  246.             window=0;                        /* adjust real space window */
  247.             }
  248.          page=0;
  249.          }
  250.       else if ((diff+velocity) >= (PAGE_SIZE-DISPLAY_SIZE))
  251.          {                                    /* notify main program of upcoming bitmap shift */
  252.          if ((x_offset+velocity+DISPLAY_SIZE) < VS_X)
  253.             {
  254.             rs_offset+=PAGE_SIZE-DISPLAY_SIZE;
  255.             window=0;                        /* adjust real space window */
  256.             reset=1;                           /* flag to reset bitmap pointers */
  257.             page=1;
  258.             }
  259.          }
  260.       if (!shift)
  261.          gs_rs_window(dlist,diff,0);         /* scroll real space window over bitmap */
  262.       gs_scroll_vp(&display,0,x,0,1);         /* scroll the display during next VB */
  263.       }
  264. }
  265.  
  266. /***************************************************************************/
  267. /*
  268.    This function creates the display, loads the background picture, loads
  269.    all anim objects, allocates a display list for the animation system,
  270.    adds all objects to the list, draws the objects in the display, shows
  271.    the GDS display, and then installs the scroller.
  272. */
  273.  
  274. int setup()
  275.  
  276. {
  277.    int cnt=0;
  278.    struct anim_load_struct load;
  279.  
  280.    switch (gs_chiprev())   /* set hard left display offset depending on chipset */
  281.       {
  282.       case AGA_CHIPREV:
  283.          if (GfxBase->LibNode.lib_Version >= 36)   /* if WB 2.0 or higher */
  284.             display.DxOffset=0x87;
  285.          else
  286.             display.DxOffset=0;
  287.          break;
  288.       default:
  289.          if (GfxBase->LibNode.lib_Version >= 36)   /* if WB 2.0 or higher */
  290.             display.DxOffset=0x77;
  291.          else
  292.             display.DxOffset=0;
  293.          break;
  294.       }
  295.    gs_get_ILBM_bm(&loadpic);         /* load color table from picture file */
  296.    #ifdef NTSC_MONITOR_ID
  297.       if (GfxBase->LibNode.lib_Version >= 36)   /* if WB 2.0 or higher */
  298.          {               /* this defeats mode promotion on AGA machines */
  299.          if (ModeNotAvailable(NTSC_MONITOR_ID))
  300.             {
  301.             display.modes = PAL_MONITOR_ID;
  302.             }
  303.          else
  304.             {
  305.             display.modes = NTSC_MONITOR_ID;
  306.             }
  307.          }
  308.    #endif
  309.    if (gs_create_display(&display))
  310.       {
  311.       return(-1);
  312.       }
  313.    loadpic.bitmap1=vp.bitmap1;      /* tell picture loader where to put picture */
  314.    loadpic.bitmap2=vp.bitmap2;      /* fill both bitmaps with background picture */
  315.    while (cnt < PAGE_SIZE)      /* stagger the picture continously across bitmap width */
  316.       {
  317.       loadpic.loadx=(BMOFFSET+cnt)/8;
  318.       if (gs_loadILBM(&loadpic))
  319.          {
  320.          gs_remove_display(&display);
  321.          return(-2);
  322.          }
  323.       cnt+=bmh.w;                     /* add width of picture to load offset */
  324.       }
  325.    load.flags=ANIMLOAD_NOCOLOR;      /* don't allocate a color table */
  326.    load.cmap_size=8;                  /* number of bits per color value */
  327.    load.array_elements=ANIM_COUNT;   /* number of array elements desired */
  328.    load.filename="anim/rollcrab.anim";   /* name of anim file */
  329.    if (gs_load_anim(&load))         /* load the anim object */
  330.       {
  331.       cleanup();
  332.       return(-3);
  333.       }
  334.    rollcrab=load.anim_ptr.anim;      /* ptr to anim object */
  335.    load.filename="anim/coral1.anim";   /* name of anim file */
  336.    if (gs_load_anim(&load))         /* load the anim object */
  337.       {
  338.       cleanup();
  339.       return(-3);
  340.       }
  341.    coral1=load.anim_ptr.anim;         /* ptr to anim object */
  342.    load.filename="anim/coral2.anim";   /* name of anim file */
  343.    if (gs_load_anim(&load))         /* load the anim object */
  344.       {
  345.       cleanup();
  346.       return(-3);
  347.       }
  348.    coral2=load.anim_ptr.anim;         /* ptr to anim object */
  349. //   load.filename="anim/coral3.anim";   /* name of anim file */
  350. //   if (gs_load_anim(&load))         /* load the anim object */
  351. //      {
  352. //      cleanup();
  353. //      return(-3);
  354. //      }
  355. //   coral3=load.anim_ptr.anim;         /* ptr to anim object */
  356.    load.filename="cplx/fish1.cplx";   /* name of anim file */
  357.    if (gs_load_anim(&load))         /* load the anim object */
  358.       {
  359.       cleanup();
  360.       return(-4);
  361.       }
  362.    fish1=load.anim_ptr.cplx;         /* ptr to anim object */
  363.    load.filename="cplx/fish2.cplx";   /* name of anim file */
  364.    if (gs_load_anim(&load))         /* load the anim object */
  365.       {
  366.       cleanup();
  367.       return(-5);
  368.       }
  369.    fish2=load.anim_ptr.cplx;         /* ptr to anim object */
  370.    load.filename="cplx/fish3.cplx";   /* name of anim file */
  371.    if (gs_load_anim(&load))         /* load the anim object */
  372.       {
  373.       cleanup();
  374.       return(-6);
  375.       }
  376.    fish3=load.anim_ptr.cplx;         /* ptr to anim object */
  377.    load.filename="cplx/aquadino.cplx";   /* name of anim file */
  378.    if (gs_load_anim(&load))         /* load the anim object */
  379.       {
  380.       cleanup();
  381.       return(-7);
  382.       }
  383.    aquadino=load.anim_ptr.cplx;         /* ptr to anim object */
  384.    if ((dlist=gs_get_display_list()) < 0)   /* allocate a display list for anims */
  385.       {
  386.       cleanup();
  387.       return(-8);
  388.       }
  389.    gs_init_anim(dlist,vp.bitmap1,vp.bitmap2,NULL);   /* tell anim system about bitmaps */
  390.    gs_rs_dim(dlist,DISPLAY_SIZE+(BMOFFSET*2),BMHEIGHT);   /* set new real space dimensions */
  391.          /* define area in which anim objects will be allowed to wander */
  392.    gs_set_anim_bounds(dlist,LEFT_BOUNDS,TOP_BOUNDS,RIGHT_BOUNDS,BOTTOM_BOUNDS);
  393.    if (place_anim_bottom(rollcrab))   /* now place all anim objects in the virtual area */
  394.       {
  395.       cleanup();
  396.       return(-10);
  397.       }
  398.    if (place_anim_bottom(coral1))
  399.       {
  400.       cleanup();
  401.       return(-11);
  402.       }
  403.    if (place_anim_bottom(coral2))
  404.       {
  405.       cleanup();
  406.       return(-12);
  407.       }
  408. //   if (place_anim_bottom(coral3))
  409. //      {
  410. //      cleanup();
  411. //      return(-13);
  412. //      }
  413.    if (place_cplx_bottom(aquadino))
  414.       {
  415.       cleanup();
  416.       return(-14);
  417.       }
  418.    if (place_cplx(fish1))
  419.       {
  420.       cleanup();
  421.       return(-15);
  422.       }
  423.    if (place_cplx(fish2))
  424.       {
  425.       cleanup();
  426.       return(-16);
  427.       }
  428.    if (place_cplx(fish3))
  429.       {
  430.       cleanup();
  431.       return(-17);
  432.       }
  433.    gs_draw_anims(dlist);            /* actually draw anims in 2nd bitmap */
  434.    check_bounds();                  /* check to see if any need to turn around */
  435.    gs_next_anim_page(dlist);         /* tell animation system to use other bitmap next time */
  436.    gs_show_display(&display,1);      /* show the display */
  437.    gs_flip_display(&display,1);      /* flip to next bitmap page during next vertical blank */
  438.    gs_open_vb_timer();               /* open the super efficient GDS vertical blank timer */
  439.    gs_vb_timer_reset();
  440.    while (!gs_vb_time());            /* sync gfx with display */
  441.    gs_vb_timer_reset();               /* reset counter to zero */
  442.    scroller=gs_add_vb_server(&scroll,0);   /* add scroller function to vertical blank server chain */
  443.    if (!scroller)
  444.       {
  445.       cleanup();
  446.       return(-9);
  447.       }
  448.    return(0);                        /* all went well */
  449. }
  450.  
  451. /***************************************************************************/
  452. /*
  453.    Place a simple anim object on the see bottom
  454. */
  455.  
  456. int place_anim_bottom(anim)
  457. struct anim_struct *anim;
  458.  
  459. {
  460.    int cnt;
  461.  
  462.    for (cnt=0; cnt < ANIM_COUNT; cnt++)
  463.       {
  464.       anim[cnt].x = gs_random(VS_X);   /* random X,Y coords */
  465.       anim[cnt].y = gs_random(BOTTOM_SPACE)+(BOTTOM_BOUNDS-BOTTOM_SPACE)-anim[cnt].height;
  466.       anim[cnt].xa = gs_random(ANIM_SPEED) +1;   /* use xa field for object speed */
  467.                                        /* we can do this since object is not attached to */
  468.                                        /* anything, and the field would go unused otherwise */
  469.       if (cnt&1)
  470.          {
  471.          anim[cnt].xa=-anim[cnt].xa;
  472.          }
  473.       anim[cnt].prio = anim[cnt].y+anim[cnt].height;   /* obj priority setting */
  474.       if (gs_add_anim(dlist,(struct anim_struct *)&anim[cnt],anim[cnt].x,anim[cnt].y))
  475.          {                           /* if can't add object to display list */
  476.          return(-1);                  /* return failure */
  477.          }
  478.       gs_set_anim_cell((struct anim_struct *)&anim[cnt],gs_random(anim[cnt].count));
  479.       }
  480.    return(0);
  481. }
  482.  
  483. /***************************************************************************/
  484.  
  485. int place_cplx_bottom(cplx)
  486. struct anim_cplx *cplx;
  487.  
  488. {
  489.    int cnt,seq,x,y;
  490.  
  491.    for (cnt=0; cnt < ANIM_COUNT; cnt++)
  492.       {
  493.       x = gs_random(VS_X);            /* random X,Y coords */
  494.       y = gs_random(BOTTOM_SPACE)+(BOTTOM_BOUNDS-BOTTOM_SPACE)
  495.          -cplx[cnt].height;
  496.       seq=1;
  497.       cplx[cnt].list->xa = gs_random(ANIM_SPEED) +1;   /* use xa field for object speed */
  498.       if (cnt&1)
  499.          {
  500.          seq=0;
  501.          cplx[cnt].list->xa=-cplx[cnt].list->xa;
  502.          }
  503.       if (gs_add_anim_cplx(dlist,(struct anim_cplx *)&cplx[cnt],x,y,seq,y+cplx[cnt].height))
  504.          {                           /* if can't add object to display list */
  505.          return(-1);                  /* return failure */
  506.          }
  507.       gs_set_cplx_cell((struct anim_cplx *)&cplx[cnt],
  508.          gs_random(cplx[cnt].list->count));
  509.       }
  510.    return(0);
  511. }
  512.  
  513. /***************************************************************************/
  514.  
  515. int place_cplx(cplx)
  516. struct anim_cplx *cplx;
  517.  
  518. {
  519.    int cnt,seq,x,y,pre_y;
  520.  
  521.    pre_y = BOTTOM_BOUNDS-TOP_BOUNDS+12-cplx->height;
  522.    for (cnt=0; cnt < ANIM_COUNT; cnt++)
  523.       {
  524.       x = gs_random(VS_X);            /* random X,Y coords */
  525.       y = gs_random(pre_y)+TOP_BOUNDS;
  526.       seq=1;
  527.       cplx[cnt].list->xa = gs_random(ANIM_SPEED) +1;   /* use xa field for object speed */
  528.       if (cnt&1)
  529.          {
  530.          seq=0;
  531.          cplx[cnt].list->xa=-cplx[cnt].list->xa;
  532.          }
  533.       if (gs_add_anim_cplx(dlist,(struct anim_cplx *)&cplx[cnt],x,y,seq,y+cplx[cnt].height))
  534.          {                           /* if can't add object to display list */
  535.          return(-1);                  /* return failure */
  536.          }
  537.       gs_set_cplx_cell((struct anim_cplx *)&cplx[cnt],
  538.          gs_random(cplx[cnt].list->count));
  539.       }
  540.    return(0);
  541. }
  542.  
  543. /***************************************************************************/
  544. /*
  545.    This handles movement & animation of all objects.  It also continuously
  546.    redraws all objects in case the bitmap pointers have been reset (see the
  547.    scroll routine).
  548. */
  549.  
  550. void move_creatures()
  551.  
  552. /* move & animate everything */
  553.  
  554. {
  555.    unsigned long time;
  556.  
  557.    if (reset)                           /* if bitmap pointers being reset */
  558.       {
  559.       reset=0;
  560.       gs_rs_offset(dlist,rs_offset,0);   /* adjust real space offset for anims */
  561.       gs_rs_window(dlist,window,0);      /* adjust real space window over bitmap */
  562.       }
  563.    time = gs_vb_time();                  /* get value of vertical blank timer */
  564.    if (time >= VB_DELAY)               /* don't go too fast */
  565.       {
  566.       gs_vb_timer_reset();               /* reset vertical blank timer */
  567.       move_anim(rollcrab);
  568.       move_cplx(aquadino);
  569.       move_cplx(fish1);
  570.       move_cplx(fish2);
  571.       move_cplx(fish3);
  572.       while (display.flags & GSV_FLIP); /* while page not flipped yet */
  573.       gs_draw_anims(dlist);            /* draw them anim objects! */
  574.       gs_flip_display(&display,1);      /* switch to other display, sync */
  575.       gs_next_anim_page(dlist);         /* tell anim sys to use other bitmap */
  576.       check_bounds();                  /* turn around at virtual space bounds */
  577.       }
  578.    else
  579.       {
  580.       while (display.flags & GSV_FLIP); /* while page not flipped yet */
  581.       gs_draw_anims(dlist);            /* draw them anim objects! */
  582.       gs_flip_display(&display,1);      /* switch to other display, sync */
  583.       gs_next_anim_page(dlist);         /* tell anim sys to use other bitmap */
  584.       }
  585. }
  586.  
  587. /***************************************************************************/
  588.  
  589. void move_anim(anim)
  590. struct anim_struct *anim;
  591.  
  592. {
  593.    int cnt;
  594.  
  595.    for (cnt=0; cnt < ANIM_COUNT; cnt++)
  596.       {
  597.       anim[cnt].y+=anim[cnt].xa;
  598.       gs_anim_obj((struct anim_struct *)&anim[cnt],anim[cnt].x,anim[cnt].y);
  599.       }
  600. }
  601.  
  602. /***************************************************************************/
  603.  
  604. void move_cplx(cplx)
  605. struct anim_cplx *cplx;
  606.  
  607. {
  608.    int cnt,x;
  609.  
  610.    for (cnt=0; cnt < ANIM_COUNT; cnt++)
  611.       {
  612.       x=cplx[cnt].anim->x+cplx[cnt].list->xa;   /* move the object */
  613.       gs_anim_cplx((struct anim_cplx *)&cplx[cnt],x,cplx[cnt].anim->y);
  614.       }
  615. }
  616.  
  617. /***************************************************************************/
  618.  
  619. void check_bounds()
  620.  
  621. {
  622.    check_anim_bounds(rollcrab);
  623.    check_cplx_bounds(aquadino);
  624.    check_cplx_bounds(fish1);
  625.    check_cplx_bounds(fish2);
  626.    check_cplx_bounds(fish3);
  627. }
  628.  
  629. /***************************************************************************/
  630. /*
  631.    This function checks against top & bottom boundaries for the rollcrab, and
  632.    reverses direction accordingly.
  633. */
  634.  
  635. void check_anim_bounds(anim)
  636. struct anim_struct *anim;
  637.  
  638. {
  639.    int cnt;
  640.  
  641.    for (cnt=0; cnt < ANIM_COUNT; cnt++)
  642.       {
  643.       if (anim[cnt].flags & (ANIM_BOUNDS_Y1|ANIM_BOUNDS_Y2))
  644.          {
  645.          anim[cnt].xa=-anim[cnt].xa;   /* reverse X direction */
  646.          }
  647.       }
  648. }
  649.  
  650. /***************************************************************************/
  651. /*
  652.    This function checks against left & right boundaries for all other
  653.    creatures, and reverses direction accordingly.
  654. */
  655.  
  656. void check_cplx_bounds(cplx)
  657. struct anim_cplx *cplx;
  658.  
  659. {
  660.    int cnt;
  661.  
  662.    for (cnt=0; cnt < ANIM_COUNT; cnt++)
  663.       {
  664.       if (cplx[cnt].anim->flags & (ANIM_BOUNDS_X1|ANIM_BOUNDS_X2))
  665.          {
  666.          cplx[cnt].list->xa=-cplx[cnt].list->xa;   /* reverse X direction */
  667.          gs_set_cplx_seq((struct anim_cplx *)&cplx[cnt],cplx[cnt].seq^1,
  668.             cplx[cnt].anim->x,cplx[cnt].anim->y);
  669.          }
  670.       }
  671. }
  672.  
  673. /***************************************************************************/
  674.  
  675. int check_close()
  676.  
  677. /* check for left mouse button click */
  678.  
  679. {
  680.    if (gs_joystick(0) & (JOY_BUTTON1|JOY_BUTTON2))
  681.       return(1);
  682.    return(0);
  683. }
  684.  
  685. /***************************************************************************/
  686.  
  687. void cleanup()
  688.  
  689. /* release all resources and memory */
  690.  
  691. {
  692.    gs_close_vb_timer();
  693.    if (dlist > -1)
  694.       gs_free_display_list(dlist);
  695.    if (scroller)
  696.       gs_remove_vb_server(scroller);
  697.    if (rollcrab)
  698.       gs_free_anim(rollcrab,ANIM_COUNT);
  699.    if (coral1)
  700.       gs_free_anim(coral1,ANIM_COUNT);
  701.    if (coral2)
  702.       gs_free_anim(coral2,ANIM_COUNT);
  703.    if (coral3)
  704.       gs_free_anim(coral3,ANIM_COUNT);
  705.    if (fish1)
  706.       gs_free_cplx(fish1,ANIM_COUNT);
  707.    if (fish2)
  708.       gs_free_cplx(fish2,ANIM_COUNT);
  709.    if (fish3)
  710.       gs_free_cplx(fish3,ANIM_COUNT);
  711.    if (aquadino)
  712.       gs_free_cplx(aquadino,ANIM_COUNT);
  713.    gs_remove_display(&display);
  714. }
  715.